/*     */ package com.zimbra.cs.zimlet;
/*     */ 
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.TemplateCompiler;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Config;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Zimlet;
/*     */ import com.zimbra.cs.service.admin.AdminAccessControl;
/*     */ import com.zimbra.cs.servlet.ZimbraServlet;
/*     */ import java.io.File;
/*     */ import java.io.IOException;
/*     */ import java.util.Iterator;
/*     */ import java.util.LinkedHashSet;
/*     */ import java.util.LinkedList;
/*     */ import java.util.List;
/*     */ import java.util.Set;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ import javax.servlet.Filter;
/*     */ import javax.servlet.FilterChain;
/*     */ import javax.servlet.FilterConfig;
/*     */ import javax.servlet.ServletException;
/*     */ import javax.servlet.ServletRequest;
/*     */ import javax.servlet.ServletResponse;
/*     */ import javax.servlet.http.HttpServletRequest;
/*     */ import javax.servlet.http.HttpServletResponse;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class ZimletFilter
/*     */   extends ZimbraServlet
/*     */   implements Filter
/*     */ {
/*     */   public static final String ALL_ZIMLETS = "com.zimbra.cs.zimlet.All";
/*     */   public static final String ALLOWED_ZIMLETS = "com.zimbra.cs.zimlet.Allowed";
/*     */   private static final String ZIMLET_URL = "^/service/zimlet/(?:_dev/)?([^/\\?]+)([/\\?]?)(.*)$";
/*     */   private static final String ZIMLET_RES_URL_PREFIX = "/service/zimlet/res/";
/*     */   private Pattern mPattern;
/*     */   
/*     */   public void init(FilterConfig config)
/*     */     throws ServletException
/*     */   {
/*  58 */     this.mPattern = Pattern.compile("^/service/zimlet/(?:_dev/)?([^/\\?]+)([/\\?]?)(.*)$");
/*     */   }
/*     */   
/*     */   private boolean isHttpReq(ServletRequest req, ServletResponse res) {
/*  62 */     return ((req instanceof HttpServletRequest)) && ((res instanceof HttpServletResponse));
/*     */   }
/*     */   
/*     */   private AuthToken getAuthTokenForApp(HttpServletRequest req, HttpServletResponse resp, boolean doNotSendHttpError)
/*     */     throws IOException, ServiceException
/*     */   {
/*  68 */     Config config = Provisioning.getInstance().getConfig();
/*  69 */     int adminPort = config.getIntAttr("zimbraAdminPort", 0);
/*  70 */     if (adminPort == req.getLocalPort()) {
/*  71 */       return getAdminAuthTokenFromCookie(req, resp, doNotSendHttpError);
/*     */     }
/*  73 */     return getAuthTokenFromCookie(req, resp, doNotSendHttpError);
/*     */   }
/*     */   
/*     */   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
/*     */   {
/*  78 */     if (!isHttpReq(request, response)) {
/*  79 */       return;
/*     */     }
/*  81 */     HttpServletRequest req = (HttpServletRequest)request;
/*  82 */     HttpServletResponse resp = (HttpServletResponse)response;
/*     */     AuthToken authToken;
/*     */     try
/*     */     {
/*  86 */       authToken = getAuthTokenForApp(req, resp, false);
/*     */     } catch (ServiceException se) {
/*  88 */       ZimbraLog.zimlet.info("can't get authToken: " + se.getMessage());
/*  89 */       resp.sendError(403);
/*  90 */       return;
/*     */     }
/*     */     
/*  93 */     if (authToken == null)
/*     */     {
/*  95 */       return;
/*     */     }
/*     */     
/*  98 */     boolean isAdminAuth = false;
/*     */     
/*     */ 
/*     */ 
/* 102 */     Provisioning prov = Provisioning.getInstance();
/* 103 */     List<Zimlet> allowedZimlets = new LinkedList();
/* 104 */     List<Zimlet> allZimlets = new LinkedList();
/*     */     try {
/* 106 */       isAdminAuth = AdminAccessControl.getAdminAccessControl(authToken).isSufficientAdminForZimletFilterServlet();
/*     */       
/*     */ 
/* 109 */       if (!isAdminAuth)
/*     */       {
/* 111 */         Account account = prov.get(Key.AccountBy.id, authToken.getAccountId(), authToken);
/* 112 */         for (String zimletName : ZimletUtil.getAvailableZimlets(account).getZimletNamesAsArray()) {
/* 113 */           Zimlet zimlet = prov.getZimlet(zimletName);
/* 114 */           if (zimlet != null) {
/* 115 */             if (zimlet.isEnabled()) {
/* 116 */               allowedZimlets.add(zimlet);
/*     */             }
/* 118 */             allZimlets.add(zimlet);
/*     */           }
/*     */         }
/*     */       }
/*     */       else
/*     */       {
/* 124 */         allZimlets = prov.listAllZimlets();
/* 125 */         Iterator<Zimlet> iter = allZimlets.iterator();
/* 126 */         while (iter.hasNext()) {
/* 127 */           Zimlet zimlet = (Zimlet)iter.next();
/* 128 */           if ((zimlet.isExtension()) && 
/* 129 */             (zimlet.isEnabled())) {
/* 130 */             allowedZimlets.add(zimlet);
/*     */           }
/*     */         }
/*     */       }
/*     */     }
/*     */     catch (ServiceException e)
/*     */     {
/* 137 */       ZimbraLog.zimlet.info("unable to get list of zimlets");
/* 138 */       resp.sendError(403);
/* 139 */       return;
/*     */     }
/*     */     
/*     */ 
/* 143 */     List<Zimlet> zimletList = ZimletUtil.orderZimletsByPriority(allowedZimlets);
/* 144 */     Set<String> allowedZimletNames = getZimletNames(zimletList);
/* 145 */     Set<String> allZimletNames = getZimletNames(allZimlets);
/*     */     
/*     */ 
/* 148 */     Set<String> zimletNames = new LinkedHashSet();
/* 149 */     String uri = req.getRequestURI();
/* 150 */     boolean isZimletRes = uri.startsWith("/service/zimlet/res/");
/* 151 */     if (isZimletRes) {
/* 152 */       zimletNames.addAll(allowedZimletNames);
/*     */     }
/*     */     else {
/* 155 */       Matcher matcher = this.mPattern.matcher(uri);
/* 156 */       if (!matcher.matches()) {
/* 157 */         ZimbraLog.zimlet.info("no zimlet specified in request");
/* 158 */         resp.sendError(403);
/* 159 */         return;
/*     */       }
/* 161 */       zimletNames.add(matcher.group(1));
/*     */     }
/*     */     
/*     */ 
/* 165 */     File basedir = new File(LC.zimlet_directory.value());
/* 166 */     File devdir = new File(basedir, "_dev");
/* 167 */     Iterator<String> iter = zimletNames.iterator();
/* 168 */     while (iter.hasNext()) {
/* 169 */       String zimletName = (String)iter.next();
/*     */       try {
/* 171 */         File devfile = new File(devdir, zimletName);
/* 172 */         if (!devfile.exists())
/*     */         {
/*     */ 
/*     */ 
/* 176 */           Zimlet zimlet = prov.getZimlet(zimletName);
/* 177 */           if (zimlet == null) {
/* 178 */             ZimbraLog.zimlet.info("no such zimlet: " + zimletName);
/* 179 */             iter.remove();
/* 180 */             allZimlets.remove(zimlet);
/*     */ 
/*     */ 
/*     */           }
/* 184 */           else if (!allowedZimletNames.contains(zimletName)) {
/* 185 */             ZimbraLog.zimlet.info("unauthorized request to zimlet " + zimletName + " from user " + authToken.getAccountId());
/* 186 */             iter.remove();
/* 187 */             allZimlets.remove(zimlet);
/*     */ 
/*     */ 
/*     */           }
/* 191 */           else if ((zimlet.isExtension()) && (!isAdminAuth))
/*     */           {
/* 193 */             iter.remove();
/* 194 */             allZimlets.remove(zimlet);
/*     */           }
/*     */         }
/*     */       } catch (ServiceException se) {
/* 198 */         ZimbraLog.zimlet.info("service exception to zimlet " + zimletName + " from user " + authToken.getAccountId() + ": " + se.getMessage());
/* 199 */         iter.remove();
/*     */       }
/*     */     }
/*     */     
/* 203 */     if (!isZimletRes) {
/* 204 */       Matcher matcher = this.mPattern.matcher(uri);
/* 205 */       if (matcher.matches()) {
/* 206 */         String zimletName = matcher.group(1);
/* 207 */         if (!zimletNames.contains(zimletName)) {
/* 208 */           resp.sendError(403);
/* 209 */           return;
/*     */         }
/*     */       }
/*     */     }
/*     */     
/*     */ 
/* 215 */     if (uri.endsWith(".template.js")) {
/* 216 */       Matcher matcher = this.mPattern.matcher(uri);
/* 217 */       if (matcher.matches()) {
/* 218 */         String zimletName = matcher.group(1);
/* 219 */         String opath = matcher.group(3);
/* 220 */         String ipath = opath.replaceAll(".js$", "");
/* 221 */         boolean isDevZimlet = uri.indexOf("_dev") != -1;
/* 222 */         File zimletDir = new File(isDevZimlet ? devdir : basedir, zimletName);
/* 223 */         File ifile = new File(zimletDir, ipath);
/* 224 */         File ofile = new File(zimletDir, opath);
/* 225 */         if ((!ofile.exists()) || ((ifile.exists()) && (ifile.lastModified() > ofile.lastModified()))) {
/* 226 */           String prefix = zimletName + ".";
/*     */           try {
/* 228 */             TemplateCompiler.compile(zimletDir, zimletDir, prefix, new String[] { ipath }, true, true);
/*     */           }
/*     */           catch (IOException e) {}
/*     */         }
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 240 */     req.setAttribute("com.zimbra.cs.zimlet.Allowed", zimletNames);
/* 241 */     req.setAttribute("com.zimbra.cs.zimlet.All", allZimletNames);
/* 242 */     chain.doFilter(req, resp);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public void destroy() {}
/*     */   
/*     */ 
/*     */ 
/*     */   private static Set<String> getZimletNames(List<Zimlet> zimlets)
/*     */   {
/* 254 */     Set<String> names = new LinkedHashSet();
/* 255 */     for (Zimlet zimlet : zimlets) {
/* 256 */       names.add(zimlet.getName());
/*     */     }
/* 258 */     return names;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/zimlet/ZimletFilter.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */